/**
 *
 */
package com.angel.dao.generic.helpers;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Restrictions;
import org.hibernate.transform.Transformers;

import com.angel.common.helpers.StringHelper;

/**
 *
 * @author William
 */
public class HibernateCriteriaHelper {

	private HibernateCriteriaHelper(){
		super();
	}

	public static <T extends Object> Query createQuery(Session session, Map<String, Object> properties, String query, Class<T> persistentClass){
		if(!StringHelper.isEmpty(query)){
			boolean begins = StringHelper.beginsWith(query.trim(), GenericHibernateDAOConstants.WHERE_SQL_CLAUSE.trim());
			if(!begins){
				query = GenericHibernateDAOConstants.WHERE_SQL_CLAUSE + query;
			}
		}
		Query aQuery = session.createQuery(GenericHibernateDAOConstants.FROM_SQL_CLAUSE + persistentClass.getName() + " " + query);
		if(properties != null){
			for(String property: properties.keySet()){
				aQuery = aQuery.setParameter(property, properties.get(property));
			}
		}
		return aQuery;
	}

	public static Query createHQLQuery(Session session, Map<String, Object> properties, String query){
		Query aQuery = session.createQuery(query);
		if(properties != null){
			for(String property: properties.keySet()){
				aQuery = aQuery.setParameter(property, properties.get(property));
			}
		}
		return aQuery;
	}

	@SuppressWarnings("unchecked")
	public static <C> Collection<C> transformResultListQueryToBeanClass(Query query, Class<C> beanClass){
		query.setResultTransformer(Transformers.aliasToBean(beanClass));
        Collection<C> resultList = query.list();
        return resultList;
	}

	@SuppressWarnings("unchecked")
	public static <C> C transformUniqueResultQueryToBeanClass(Query query, Class<C> beanClass){
		query.setResultTransformer(Transformers.aliasToBean(beanClass));
        C uniqueResult = (C) query.uniqueResult();
        return uniqueResult;
	}

	public static <T extends Object> Criteria buildCriteriaFor(Session session, Class<T> persistentClass, Criterion... criterion){
    	Criteria criteria = session.createCriteria(persistentClass);
        for (Criterion c : criterion) {
        	criteria.add(c);
        }
        return criteria;
    }

	public static <T extends Object> Criteria buildCriteriaWith(Session session, Class<T> persistentClass, Map<String,Object> propertiesValues){
		List<Criterion> criterions = new ArrayList<Criterion>();
		Set<String> keysSet = propertiesValues.keySet();
		for(String key: keysSet){
			Object value = propertiesValues.get(key);
			criterions.add(Restrictions.eq(key, value));
		}
		return buildCriteriaWith(session, persistentClass, criterions);
	}

	public static <T extends Object> Criteria buildCriteriaWith(Session session, Class<T> persistentClass, List<Criterion> criterions){
		Criteria criteria = buildCriteriaFor(session, persistentClass);
		for(Criterion c: criterions){
			criteria.add(c);
		}
		return criteria;
	}
}
